﻿using Compunet.YoloSharp;
using Compunet.YoloSharp.Plotting;
using Microsoft.Win32;
using OpenCvSharp;
using SixLabors.ImageSharp.Formats.Png;
using System.IO;
using System.Windows;
using System.Windows.Media;
using System.Windows.Media.Imaging;

namespace YOLOSharpDemo
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : System.Windows.Window
    {
        public MainWindow()
        {
            InitializeComponent();
            Loaded += MainWindow_Loaded;
        }
        YoloPredictor _detectPredictor;
        public DelegateCommand<string> Cmd => new DelegateCommand<string>(async cmd => 
        {
        switch(cmd)
            {
                default:
                    {
                        await Task.Delay(100);
                        break;
                    }
                case "LoadImage":
                    {
                        var dlg = new OpenFileDialog()
                        {
                            //DefaultDirectory = Directory.GetCurrentDirectory()
                        };
                        var ret = dlg.ShowDialog();
                        if(ret == true)
                        {
                            var image1 = SixLabors.ImageSharp.Image.Load(dlg.FileName);
                            var result = await _detectPredictor.DetectAsync(image1);
                            SixLabors.ImageSharp.Image plotted = await result.PlotImageAsync(image1);
                            ImageView.WImage = ToWriteableBitmap(plotted);
                            ImageView.RaisePropertyChanged("WImage");
                        }
                        break;
                    }
            }
        });
        private async void MainWindow_Loaded(object sender, RoutedEventArgs e)
        {
            var mat = LoadImageFromFile("apple_1.png");
            ImageView.UpdateWImage(mat.Data, (int)GetMatDataSize(mat), GetMatImageType(mat), mat.Width, mat.Height);
            _detectPredictor = new YoloPredictor("./models/yolo11n.onnx");
            var task = _detectPredictor.Metadata.Task;
            var image1 = SixLabors.ImageSharp.Image.Load("apple_1.png");
            var result = await _detectPredictor.DetectAsync(image1);
            SixLabors.ImageSharp.Image plotted = await result.PlotImageAsync(image1);
            ImageView.WImage = ToWriteableBitmap(plotted);
            ImageView.RaisePropertyChanged("WImage");
            //using (MemoryStream memoryStream = new MemoryStream())
            //{
            //    // 保存ImageSharp图像到内存流中
            //    plotted.Save(memoryStream, new PngEncoder());
            //    //var bitmap = new Bitmap(memoryStream);
            //}
            ////plotted.SaveAsPng("apple_1_detected.png");
        }
        public static Mat LoadImageFromFile(string path)
        {
            return Cv2.ImRead(path, ImreadModes.AnyColor);
        }
        public static PixelFormat GetMatImageType(Mat image)
        {
            var typOri = image.Type();
            var ret = PixelFormats.Default;

            if (typOri == MatType.CV_8UC1)
            {
                ret = PixelFormats.Gray8;
            }
            else if (typOri == MatType.CV_8UC3)
            {
                ret = PixelFormats.Bgr24;
            }

            return ret;
        }
        public static long GetMatDataSize(Mat image)
        {
            return image.Total() * image.Channels();
        }
        private WriteableBitmap ToWriteableBitmap(SixLabors.ImageSharp.Image image)
        {
            // Convert the generic Image to a specific pixel format (Bgra32)
            var imageBgra32 = image.CloneAs<SixLabors.ImageSharp.PixelFormats.Bgra32>();

            // Get pixel data from the converted image
            byte[] pixelBytes = new byte[imageBgra32.Width * imageBgra32.Height * System.Runtime.CompilerServices.Unsafe.SizeOf<SixLabors.ImageSharp.PixelFormats.Bgra32>()];
            imageBgra32.CopyPixelDataTo(pixelBytes);

            // Create a WriteableBitmap and copy the pixel data
            var result = new System.Windows.Media.Imaging.WriteableBitmap(imageBgra32.Width, imageBgra32.Height, 96, 96, System.Windows.Media.PixelFormats.Bgra32, null);
            result.Lock();
            unsafe
            {
                fixed (byte* sourceBufferPtr = pixelBytes)
                {
                    Buffer.MemoryCopy(sourceBufferPtr, (void*)result.BackBuffer, pixelBytes.Length, pixelBytes.Length);
                }
            }
            result.AddDirtyRect(new System.Windows.Int32Rect(0, 0, result.PixelWidth, result.PixelHeight));
            result.Unlock();

            return result;
        }
    }
}